package cn.klaw.config;

import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.SmartInitializingSingleton;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 程序启动线程初始化类
 */
@Slf4j
public class ApplicationStartErrorCheck implements SmartInitializingSingleton {

    private static boolean startError = false;

    @Getter
    private static final ThreadPoolExecutor applicationInitThreadPool = new ThreadPoolExecutor(10, Integer.MAX_VALUE,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>());

    public static void setStartError() {
        ApplicationStartErrorCheck.startError = true;
    }

    @SneakyThrows
    @Override
    public void afterSingletonsInstantiated() {
        long count = 0;
        long sleep = 100L;
        //最多等待程序启动5分钟
        long maxCount = 5 * 60000 / sleep;
        boolean isComplete = true;
        // 等待异步初始化全部完成
        while(!applicationInitThreadPool.getQueue().isEmpty() || applicationInitThreadPool.getActiveCount() > 0){
            if(log.isDebugEnabled()) {
                log.error("等待初始化线程全部结束");
            }
            Thread.sleep(sleep);
            if(++count > maxCount){
                isComplete = false;
                break;
            }
        }
        if(!isComplete){
            log.error("容器初始化时间过长 请检查是否存在问题");
            System.exit(0);
        }
        if(startError){
            log.error("Bean初始化发生错误, 请检查启动日志");
            System.exit(0);
        }
//        System.out.println("延迟五秒");
//        Thread.sleep(5000L);
        if(log.isDebugEnabled()) {
            log.debug("容器初始化结束");
        }
    }
}
